/**
 * ...
 * @author Franco Ponticelli
 */

package uform.property;

import hxevents.Notifier;
import thx.util.Result;
import thx.util.Message;

class Property<T> implements IProperty<T>
{
	public var onChange(getOnChange, null) : Notifier;
	public var validators(getValidators, null) : List<T -> Result>;
	var _value : Null<T>;
	var _default : Null<T>;
	var _onChange : Notifier;
	var _validators : List < T -> Result > ;
	var _valid : Result;
	var _old : Null<T>;
	public function new(?defaultValue : Null<T>)
	{
		_value = _default = defaultValue;
		_valid = Result.Ok;
		_old = null;
	}
	
	public function reset() : IProperty<T>
	{
		set(_default);
		return this;
	}
	
	public function getValue()
	{
		return _value;
	}
	
	public function get()
	{
		return null == _value ? _default : _value;
	}
	
	public function set(v : Null<T>) : IProperty<T>
	{                  
		if (v == _value)
			return this;
		_old = get();
		_value = v;
		
		if (null != _onChange)
			_onChange.dispatch();
		return this;
	}
	
	public function getOld()
	{
		return _old;
	}
	
	public function hasValue()
	{
		return null != _value;
	}
	
	public function isNull()
	{
		return null == get();
	}
	
	public function getAlt(alt : T)
	{
		if (isNull())
			return alt;
		else
			return get();
	}
	
	public function setDefault(v : Null<T>) : IProperty<T>
	{
		_default = v;
		return this;
	}
	
	public function getDefault()
	{
		return _default;
	}
	
	public function isValid()
	{
		switch(_valid)
		{
			case Ok:
				return true;
			case Failure(_):
				return false;
		}
	}
	
	public function getMessages() : Array<Message>
	{
		switch(_valid)
		{
			case Ok:
				return null;
			case Failure(messages):
				return messages;
		}
	}
	
	function getOnChange()
	{
		if (null == _onChange)
			_onChange = new Notifier();
		return _onChange;
	}
	
	function getValidators()
	{
		if (null == _validators)
			_validators = new List();
		return _validators;
	}
}